package org.CrossApp.lib;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

import android.os.Handler;
import android.os.Looper;
import android.util.SparseArray;
import android.view.View;
import android.widget.FrameLayout;

public class CrossAppWebViewHelper {
	
	private static final String TAG = CrossAppWebViewHelper.class.getSimpleName();
	private static Handler handler;
	private static CrossAppActivity crossAppActivity;
	private static FrameLayout layout;
	private static SparseArray<CrossAppWebView> webViews;
	private static int viewTag = 0;

	public CrossAppWebViewHelper(FrameLayout layout) {
		CrossAppWebViewHelper.layout = layout;
		handler = new Handler(Looper.myLooper());
		crossAppActivity = CrossAppActivity.getContext();
		webViews = new SparseArray<CrossAppWebView>();
	}

	private static native boolean shouldStartLoading(int index, String message);

	public static boolean _shouldStartLoading(int index, String message) {
		return !shouldStartLoading(index, message);
	}

	private static native void didFinishLoading(int index, String message);

	public static void _didFinishLoading(int index, String message) {
		didFinishLoading(index, message);
	}

	private static native void didFailLoading(int index, String message);

	public static void _didFailLoading(int index, String message) {
		didFailLoading(index, message);
	}

	private static native void onJsCallback(int index, String message);

	public static void _onJsCallback(int index, String message) {
		onJsCallback(index, message);
	}

	public static native void didLoadHtmlSource(String htmlSrc);

	public static Boolean s_bWaitGetHemlSource = false;

	public static native void pause();

	public static native void resume();

	public static void createWebView(final int index) {
		pause();
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = new CrossAppWebView(crossAppActivity, index);
				FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
				layout.addView(webView, lParams);
				webView.setDrawingCacheEnabled(true);
				webViews.put(index, webView);
			}
		});
		resume();
	}

	public static int createWebView() {
		final int index = viewTag;
		createWebView(index);
		return viewTag++;
	}

	public static void removeWebView(final int index) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webViews.remove(index);
					layout.removeView(webView);
					webView.destroy();
				}
			}
		});
	}

	public static void removeAllWebViews() {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < webViews.size(); i++) {
					CrossAppWebView webView = webViews.get(webViews.keyAt(i));
					if (webView != null) {
						layout.removeView(webView);
						webView.destroy();
					}
				}
				webViews.clear();
			}
		});
	}

	public static void setVisible(final int index, final boolean visible) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
				}
			}
		});
	}

	public static void setWebViewRect(final int index, final int left, final int top, final int maxWidth, final int maxHeight) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webView.setWebViewRect(left, top, maxWidth, maxHeight);
				}
			}
		});
	}

	public static void setJavascriptInterfaceScheme(final int index, final String scheme) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webView.setJavascriptInterfaceScheme(scheme);
				}
			}
		});
	}

	public static void loadHTMLString(final int index, final String htmlString, final String data, final String baseUrl) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webView.loadDataWithBaseURL(baseUrl, data, null, null, null);
				}
			}
		});
	}

	public static void loadUrl(final int index, final String url) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webView.loadUrl(url);
				}
			}
		});
	}

	public static void loadUrlWithRect(final int index, final String url, final String size) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					String[] s = size.split("-");
					webView.setWebViewRect(Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.parseInt(s[2]), Integer.parseInt(s[3]));
					webView.loadUrl(url);
				}
			}
		});
	}

	public static void loadFile(final int index, final String filePath) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webView.loadUrl(filePath);
				}
			}
		});
	}

	public static void getWebViewImage(final int index) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				webView.getWebViewImage();
			}
		});
	}

	public static void stopLoading(final int index) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webView.stopLoading();
				}
			}
		});
	}

	public static void reload(final int index) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webView.reload();
				}
			}
		});
	}

	public static <T> T callInMainThread(Callable<T> call) throws ExecutionException, InterruptedException {
		FutureTask<T> task = new FutureTask<T>(call);
		handler.post(task);
		
		return task.get();
	}

	public static boolean canGoBack(final int index) {
		try {
			return callInMainThread(new Callable<Boolean>() {
				@Override
				public Boolean call() throws Exception {
					CrossAppWebView webView = webViews.get(index);
					return webView != null && webView.canGoBack();
				}
			});
		} catch (ExecutionException e) {
			return false;
		} catch (InterruptedException e) {
			return false;
		}
	}

	public static boolean canGoForward(final int index) {
		try {
			return callInMainThread(new Callable<Boolean>() {
				@Override
				public Boolean call() throws Exception {
					CrossAppWebView webView = webViews.get(index);
					return webView != null && webView.canGoForward();
				}
			});
		} catch (ExecutionException e) {
			return false;
		} catch (InterruptedException e) {
			return false;
		}
	}

	public static void goBack(final int index) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webView.goBack();
				}
			}
		});
	}

	public static void goForward(final int index) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webView.goForward();
				}
			}
		});
	}

	public static void evaluateJS(final int index, final String js) {
		s_bWaitGetHemlSource = false;
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					s_bWaitGetHemlSource = true;
					webView.loadUrl("javascript:" + js);
				}
			}
		});
		try {
			while (s_bWaitGetHemlSource == false) {
				Thread.sleep(100);
			}
		} catch (Exception e) {
		}
	}

	public static void setScalesPageToFit(final int index, final boolean scalesPageToFit) {
		crossAppActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				CrossAppWebView webView = webViews.get(index);
				if (webView != null) {
					webView.setScalesPageToFit(scalesPageToFit);
				}
			}
		});
	}

	public String[] getAllWebviews() {
		String[] strs = new String[1 + webViews.size() * 3];
		int index = 0;
		strs[index++] = String.valueOf(viewTag);
		for (int i = 0; i < webViews.size(); i++) {
			CrossAppWebView webView = webViews.get(webViews.keyAt(i));
			if (webView != null) {
				strs[index++] = String.valueOf(webView.getViewTag());
				strs[index++] = webView.getUrl();
				strs[index++] = webView.getWebViewRectString();
			}
		}
		
		return strs;
	}

	public void setAllWebviews(String[] strs) {
		removeAllWebViews();
		int cnt = (strs.length - 1) / 3;
		viewTag = Integer.parseInt(strs[0]);
		for (int i = 0; i < cnt; i++) {
			int index = Integer.parseInt(strs[3 * i + 1]);
			createWebView(index);
			loadUrlWithRect(index, strs[3 * i + 2], strs[3 * i + 3]);
		}
	}
	
}